单源最短路径算法
Bellman-Ford算法
功能:求有向图中两点之间的最短距离
条件:初始化d[v]的每个元素为无穷大,记录初始点到该点的距离,初始化π[v]的元素为nul,存储最短路径中该点的前驱节点
算法描述: 从初始节点开始,选择以该节点出发的所有弧,做松弛操作,再选择新的已经未进行松弛操作的顶点,重复上述操作
松弛操作:弧(u,v) 权值w[u,v],d[v],d[u]
If(w[u,v]+d[u]<d[v]) //如果经节点u和弧(u,v)能够到v更近
d[v]=w[u,v]+d[u];//更新到v点的距离
π[v]=u;更新v点的前驱节点
伪代码:
Realx(u,v,w)
If(w[u,v]+d[u]<d[v]) //如果经节点u和弧(u,v)能够到v更近
d[v]=w[u,v]+d[u];//更新到v点的距离
π[v]=u;更新v点的前驱节点
Bellman-Ford(G,w,s)
For(v∈V) do
d[v]=maxnum;
π[v]=null;
d[s]=0;
for(u=1:n)
for(v=i+1:n)
relax(u,v,w)
For(uv∈E)
If(d[v]>d[u]+w[u,v])
Return false;
Bellman-ford算法求单源最短路径代码
#include<iostream>
usingnamespace std;
int m =100000;
int d[10];
int Pai[10];
void relax(inti, intj, intp[5][5]) {
int c = p[i][j];
if (d[i] + c < d[j])
{
d[j] = d[i] + c;
Pai[j] = i;
}
}
//运行时请释放上面的注释
intmainbell() {
/*矩阵存储图中的信息
假设条件图中有五个点,矩阵[i,j]表示节点i到节点j的弧长度
map[]={
0,5,m,m,10//m代表无穷大
m,0,2,9,3
7,m,0,6,m
m,m,4,0,m
m,2,m,1,0
}
*/
int n=5;//节点个数
for (int i = 0; i < n;i++)
d[i]= m;
d[0]= 0;
int map[5][5] = {
{0,5,m,m,10},//m代表无穷大
{m,0,2,9,3},
{7,m,0,6,m},
{m,m,4,0,m},
{m,2,m,1,m }
};
for (int i = 0; i < n;i++)
for (int j = 0; j < n;j++)
relax(i,j, map);
for (int i = 0; i < n-1;i++)
printf("%d ", d[i]);
printf("%d\n", d[n - 1]);
return 0;
}
/*
Bellman-Ford算法是对每一个边都进行松弛操作,这样算法的一部分松弛操作会是多余的,
在其基础上,每次选择剩余节点中最小的距离节点进行松弛操作,如此改进便得到了dijkstra算法
此代码展示的是dijkstra算法,
dijkstra概述:每次选剩余节点中距离最小的节点进行松弛操作,直至把所有节点选完
*/
Dijkstra算法:
伪代码:
For(v∈V) do
d[v]=maxnum;
π[v]=null;
d[s]=0;
S=null;Q=v;
while(Q!=null)
u=extrac-min(Q);
s=s∪{u};
for( v | (u,v)∈V)
relax(u,v,w)
dijstra算法求单源最短路径:
#include<iostream>
usingnamespace std;
int m =100000;
int d[10];
intflag[10];
int Pai[10];
void relax(inti, intj, intp[5][5]) {
int c = p[i][j];
if (d[i] + c < d[j])
{
d[j] = d[i] + c;
Pai[j] = i;
}
}
int main(){
/*矩阵存储图中的信息
假设条件图中有五个点,矩阵[i,j]表示节点i到节点j的弧长度
map[]={
0,5,m,m,10//m代表无穷大
m,0,2,9,3
7,m,0,6,m
m,m,4,0,m
m,2,m,1,0
}
*/
int n = 5;//节点个数
for (int i = 0; i < n;i++)
{
d[i]= m;
flag[i]= 1;
}
d[0]= 0;
int map[5][5] = {
{0,5,m,m,10 },//m代表无穷大
{m,0,2,9,3 },
{7,m,0,6,m },
{m,m,4,0,m },
{m,2,m,1,m }
};
int sum = n;
while (sum--)
{
int min_i, min=m;
for (int h = 0; h < n;h++)
if (flag[h] == 1&& d[h] < min)
{
min_i= h;
min= d[h];
}
for (int j = 0; j < n; j++)
relax(min_i,j, map);
flag[min_i]= 0;
}
for (int i = 0; i < n -1; i++)
printf("%d ", d[i]);
printf("%d\n", d[n - 1]);
return 0;
}